/**
 * Copyright 2018-2019 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.modulelink.support.refresh;

import java.util.HashSet;
import java.util.Set;

import com.jianggujin.modulelink.config.JModuleConfig;
import com.jianggujin.modulelink.magager.JModuleManager;
import com.jianggujin.modulelink.module.JModule;
import com.jianggujin.modulelink.util.JAssert;
import com.jianggujin.modulelink.util.JLogFactory;
import com.jianggujin.modulelink.util.JLogFactory.JLog;

/**
 * 刷新模块的抽象实现
 * 
 * @author jianggujin
 *
 */
public abstract class JAbstractModuleRefresh implements JModuleRefresh {
    private final JLog logger = JLogFactory.getLog(JAbstractModuleRefresh.class);
    protected final JModuleManager moduleManager;

    protected JAbstractModuleRefresh(JModuleManager moduleManager) {
        JAssert.checkNotNull(moduleManager, "moduleManager must not be null.");
        this.moduleManager = moduleManager;
    }

    /**
     * 刷新
     */
    @Override
    public synchronized void refreshModuleConfigs() {
        // 查询到的模块配置信息
        Set<JModuleConfig> queryConfigs = queryModuleConfigs();
        Set<String> moduleNames = filterModuleConfigs(queryConfigs);
        // 查询模块为空，卸载所有
        if (queryConfigs == null || queryConfigs.isEmpty()) {
            this.moduleManager.unload();
            // for (String name : this.moduleManager.getModuleNames()) {
            // try {
            // this.moduleManager.unload(name);
            // } catch (Exception e) {
            // logger.error("unload module error.", e);
            // }
            // }
            return;
        }
        // 先卸载模块，然后加载模块
        // 卸载
        for (JModule<JModuleConfig> module : this.moduleManager.getModules()) {
            JModuleConfig moduleConfig = module.getModuleConfig();
            String moduleName = moduleConfig.getModuleName();
            // 不存在，则需要卸载
            if (!moduleNames.contains(moduleName)) {
                try {
                    this.moduleManager.unload(moduleName);
                } catch (Exception e) {
                    logger.error("unload module error.", e);
                }
            }
        }

        // 加载
        for (JModuleConfig moduleConfig : queryConfigs) {
            // 模块不存在或者需要重新加载
            try {
                this.moduleManager.load(moduleConfig);
            } catch (Exception e) {
                logger.error("load module error.", e);
            }
        }
    }

    /**
     * 过滤模块配置，提取模块名称
     * 
     * @param moduleConfigs 查询到的模块
     * @return 模块名称
     */
    protected Set<String> filterModuleConfigs(Set<JModuleConfig> moduleConfigs) {
        if (moduleConfigs == null) {
            return null;
        }
        Set<String> moduleNames = new HashSet<String>();
        for (JModuleConfig moduleConfig : moduleConfigs) {
            moduleNames.add(moduleConfig.getModuleName());
        }
        return moduleNames;
    }

    /**
     * 查询所有模块配置信息
     *
     * @return 模块配置信息
     */
    protected abstract Set<JModuleConfig> queryModuleConfigs();

}
